{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Working......\n",
      "I am flying......\n",
      "i am swimming......\n"
     ]
    }
   ],
   "source": [
    "# 多继承的例子\n",
    "# 子类可以直接拥有父类的属性和方法，私有属性和方法除外\n",
    "class Fish():\n",
    "    def __init__(self,name):\n",
    "        self.name = name\n",
    "    def swim(self):\n",
    "        print(\"i am swimming......\")\n",
    "        \n",
    "class Bird():\n",
    "    def __init__(self,name):\n",
    "        self.name = name\n",
    "    \n",
    "    def fly(self):\n",
    "        print(\"I am flying......\")\n",
    "        \n",
    "class Person():\n",
    "    def __init__(self,name):\n",
    "        self.name = name\n",
    "        \n",
    "    def work(self):\n",
    "        print(\"Working......\")\n",
    "        \n",
    "# 单继承的例子\n",
    "\n",
    "class Student(Person):\n",
    "    def __init__(self,name):\n",
    "        self.name = name\n",
    "stu = Student(\"yueyue\") \n",
    "stu.work()\n",
    "    \n",
    "# 多继承的例子\n",
    "\n",
    "class SuperMan(Person,Bird,Fish):\n",
    "    def __init__(self,name):\n",
    "        self.name = name\n",
    "        \n",
    "class SwimMan(Person,Fish):\n",
    "    def __init__(self,name):\n",
    "        self.name = name\n",
    "\n",
    "s = SuperMan('yueyue')\n",
    "s.fly()\n",
    "s.swim()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 菱形继承问题\n",
    "class A():\n",
    "    pass\n",
    "class B(A):\n",
    "    pass\n",
    "class C(A):\n",
    "    pass\n",
    "\n",
    "class D(B,C):\n",
    "    pass"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "In init func\n"
     ]
    }
   ],
   "source": [
    "# 构造函数例子\n",
    "\n",
    "class Person():\n",
    "    # 对Person类进行实例化的时候\n",
    "    # 姓名要确定\n",
    "    # 年龄得确定\n",
    "    # 地址肯定有\n",
    "    def __init__(self):\n",
    "        self.name = \"NoName\"\n",
    "        self.age = 18\n",
    "        self.address = \"Studentwhonheim\"\n",
    "        print(\"In init func\")\n",
    "\n",
    "# 实例化一个人\n",
    "p = Person()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "B\n"
     ]
    }
   ],
   "source": [
    "# 构造函数的调用顺序 - 1\n",
    "# 如果子类没有写构造函数，则自动向上查找，知道找到位置\n",
    "class A():\n",
    "    def __init__(self):\n",
    "        print(\"A\")\n",
    "\n",
    "class B():\n",
    "    def __init__(self):\n",
    "        print(\"B\")\n",
    "        \n",
    "class C(B):\n",
    "    pass\n",
    "\n",
    "# 此时，首先查找c的构造函数\n",
    "# 如果没有，则向上按照MRO顺序查找父类的构造函数，直到找到为止\n",
    "c = C()\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "ename": "TypeError",
     "evalue": "__init__() missing 1 required positional argument: 'name'",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mTypeError\u001b[0m                                 Traceback (most recent call last)",
      "\u001b[0;32m<ipython-input-16-099d90d66b7b>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[1;32m     15\u001b[0m \u001b[0;31m# 如果没有，则向上按照MRO顺序查找父类的构造函数，直到找到为止\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     16\u001b[0m \u001b[0;31m# 此时，会出现参数结构不对应错误\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 17\u001b[0;31m \u001b[0mc\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mC\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[0;31mTypeError\u001b[0m: __init__() missing 1 required positional argument: 'name'"
     ]
    }
   ],
   "source": [
    "# 构造函数的调用顺序 - 2\n",
    "class A():\n",
    "    def __init__(self):\n",
    "        print(\"A\")\n",
    "\n",
    "class B():\n",
    "    def __init__(self,name):\n",
    "        print(\"B\")\n",
    "        print(name)\n",
    "        \n",
    "class C(B):\n",
    "    pass\n",
    "\n",
    "# 此时，首先查找c的构造函数\n",
    "# 如果没有，则向上按照MRO顺序查找父类的构造函数，直到找到为止\n",
    "# 此时，会出现参数结构不对应错误\n",
    "c = C()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "B\n",
      "我是C\n",
      "这是C中附加的功能\n"
     ]
    }
   ],
   "source": [
    "# 构造函数的调用顺序 - 3\n",
    "class A():\n",
    "    def __init__(self):\n",
    "        print(\"A\")\n",
    "\n",
    "class B():\n",
    "    def __init__(self,name):\n",
    "        print(\"B\")\n",
    "        print(name)\n",
    "        \n",
    "class C(B):\n",
    "    # c中想扩展B的构造函数，\n",
    "    # 即调用B的构造函数后再添加一些功能\n",
    "    # 有两种方法实现\n",
    "    # 第一种是通过父类名调用\n",
    "    '''\n",
    "    \n",
    "    def __init__(self,name):\n",
    "        # 首先调用父类的构造函数\n",
    "        B.__init__(self,name)\n",
    "        # 其次，再增加自己的功能\n",
    "        print(\"这是C中附加的功能\")\n",
    "    '''\n",
    "    \n",
    "    # 第二种，使用super\n",
    "    def __init__(self,name):\n",
    "        super(C,self).__init__(name)\n",
    "        # 其次，再增加自己的功能\n",
    "        print(\"这是C中附加的功能\")\n",
    "        \n",
    "\n",
    "# 此时，首先查找c的构造函数\n",
    "# 如果没有，则向上按照MRO顺序查找父类的构造函数，直到找到为止\n",
    "# 此时，会出现参数结构不对应错误\n",
    "c = C(\"我是C\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(<class '__main__.Tutor'>, <class '__main__.Teacher'>, <class '__main__.Student'>, <class '__main__.Person'>, <class 'object'>)\n",
      "{}\n",
      "{'__module__': '__main__', '__doc__': None}\n",
      "********************\n",
      "(<class '__main__.TutorM'>, <class '__main__.Person'>, <class '__main__.TeacherMixin'>, <class '__main__.StudentMixin'>, <class 'object'>)\n",
      "{}\n",
      "{'__module__': '__main__', '__doc__': None}\n"
     ]
    }
   ],
   "source": [
    "# Mixin 案例\n",
    "class Person():\n",
    "    name = \"liuying\"\n",
    "    age = 18\n",
    "    \n",
    "    def eat(self):\n",
    "        print(\"EAT......\")\n",
    "        \n",
    "    def drink(self):\n",
    "        print(\"DRINK....\")\n",
    "    \n",
    "    def sleep(self):\n",
    "        print(\"SLEEP....\")\n",
    "    \n",
    "class Teacher(Person):\n",
    "    def work(self):\n",
    "        print(\"Work\")\n",
    "        \n",
    "class Student(Person):\n",
    "    def study(self):\n",
    "        print(\"Study\")\n",
    "        \n",
    "class Tutor(Teacher,Student):\n",
    "    pass\n",
    "\n",
    "t = Tutor()\n",
    "\n",
    "print(Tutor.__mro__)\n",
    "print(t.__dict__)\n",
    "print(Tutor.__dict__)\n",
    "\n",
    "print(\"*\"*20)\n",
    "\n",
    "class TeacherMixin():\n",
    "    def work(self):\n",
    "        print(\"Work\")\n",
    "        \n",
    "class StudentMixin():\n",
    "    def study(self):\n",
    "        print(\"Study\")\n",
    "        \n",
    "class TutorM(Person,TeacherMixin,StudentMixin):\n",
    "    pass\n",
    "\n",
    "tt = TutorM()\n",
    "print(TutorM.__mro__)\n",
    "print(tt.__dict__)\n",
    "print(TutorM.__dict__)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "True\n",
      "False\n",
      "True\n"
     ]
    }
   ],
   "source": [
    "# issubclass\n",
    "class A():\n",
    "    pass\n",
    "\n",
    "class B(A):\n",
    "    pass\n",
    "\n",
    "class C():\n",
    "    pass\n",
    "\n",
    "print(issubclass(B,A))\n",
    "print(issubclass(C,A))\n",
    "print(issubclass(C,object))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# isinstance\n",
    "class A():\n",
    "    pass\n",
    "\n",
    "a = A()\n",
    "\n",
    "print(isinstance(a,A))\n",
    "print(isinstance(A,A))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "True\n",
      "False\n"
     ]
    }
   ],
   "source": [
    "# hasattr\n",
    "class A():\n",
    "    name = \"NoName\"\n",
    "    \n",
    "a = A()\n",
    "print(hasattr(a,\"name\"))\n",
    "print(hasattr(a,\"age\"))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Help on built-in function setattr in module builtins:\n",
      "\n",
      "setattr(obj, name, value, /)\n",
      "    Sets the named attribute on the given object to the specified value.\n",
      "    \n",
      "    setattr(x, 'y', v) is equivalent to ``x.y = v''\n",
      "\n"
     ]
    }
   ],
   "source": [
    "# help案例\n",
    "# 我想知道setattr的具体用法\n",
    "help(setattr)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['__class__',\n",
       " '__delattr__',\n",
       " '__dict__',\n",
       " '__dir__',\n",
       " '__doc__',\n",
       " '__eq__',\n",
       " '__format__',\n",
       " '__ge__',\n",
       " '__getattribute__',\n",
       " '__gt__',\n",
       " '__hash__',\n",
       " '__init__',\n",
       " '__init_subclass__',\n",
       " '__le__',\n",
       " '__lt__',\n",
       " '__module__',\n",
       " '__ne__',\n",
       " '__new__',\n",
       " '__reduce__',\n",
       " '__reduce_ex__',\n",
       " '__repr__',\n",
       " '__setattr__',\n",
       " '__sizeof__',\n",
       " '__str__',\n",
       " '__subclasshook__',\n",
       " '__weakref__']"
      ]
     },
     "execution_count": 33,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# dir 案例\n",
    "class A():\n",
    "    pass\n",
    "\n",
    "# dir(A)\n",
    "a = A()\n",
    "dir(a)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
